iT邦幫忙

2024 iThome 鐵人賽

DAY 30
0
Modern Web

關於寫react 那二三事系列 第 30

Day 30 react-beautiful-dnd(2)

  • 分享至 

  • xImage
  •  

終於來到最後一章
今天繼續說拖曳

import React, { useState } from 'react';
import { DragDropContext, Droppable, Draggable, DropResult } from 'react-beautiful-dnd';

type Item = {
  id: string;
  content: string;
};

const initialSource: Item[] = [
  { id: 'item-1', content: 'Item 1' },
  { id: 'item-2', content: 'Item 2' },
  { id: 'item-3', content: 'Item 3' },
  { id: 'item-4', content: 'Item 4' },
];

const initialTarget: Item[] = [];

const Dnd2Compnent: React.FC = () => {
  const [items, setItems] = useState<{[key:string]:Item[]}>({ source: initialSource, target: initialTarget });

  const handleOnDragEnd = (result: DropResult) => {
    if (!result.destination) return;

    const { source, destination } = result;
    if (source.droppableId === destination.droppableId) {
      const reorderedItems = Array.from(items[source.droppableId]);
      const [movedItem] = reorderedItems.splice(result.source.index, 1);
      reorderedItems.splice(result.destination.index, 0, movedItem);

      setItems({
        ...items,
        [destination.droppableId]: reorderedItems
      });
    } else {
      let it = items[source.droppableId][result.source.index];
      let sor = items[source.droppableId].filter((val:Item,inx:number)=>inx!==result.source.index);
      let reorder = [...items[destination.droppableId]];
      if (items[destination.droppableId].length > 0) {
        reorder.splice(result.destination.index, 0, it)
      } else {
        reorder.push(it)
      }
      setItems({
        [source.droppableId]: sor,
        [destination.droppableId]: reorder
      })
    }
  };

  return (
    <div className="app">
      <DragDropContext onDragEnd={handleOnDragEnd}>
        <div style={{
          backgroundColor: '#f0f0f0',
          position: 'relative',
          float: 'left',
          marginRight: '50px'
        }}>
          <Droppable droppableId="source">
            {(provided) => (
              <div
                ref={provided.innerRef}
                {...provided.droppableProps}
                style={{
                  padding: '10px',
                  width: '200px',
                  minHeight: '300px'
                }}
              >
                {items.source.map((item: Item, index: number) => (
                  <Draggable key={item.id} draggableId={item.id} index={index}>
                    {(provided) => (
                      <div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        style={{
                          ...provided.draggableProps.style,
                          userSelect: 'none',
                          padding: '16px',
                          margin: '0 0 8px 0',
                          backgroundColor: '#fff',
                          border: '1px solid #ccc',
                          borderRadius: '4px'
                        }}
                      >
                        {item.content}
                      </div>
                    )}
                  </Draggable>
                ))}
                {provided.placeholder}
              </div>
            )}
          </Droppable>
        </div>
        <div style={{
          backgroundColor: '#f0f0f0',
          position: 'relative',
          float: 'left'
        }}>
          <Droppable droppableId="target">
            {(provided) => (

              <div
                ref={provided.innerRef}
                {...provided.droppableProps}
                style={{
                  padding: '10px',
                  width: '200px',
                  minHeight: '300px'
                }}
              >
                {items.target.map((item: Item, index: number) => (
                  <Draggable key={item.id} draggableId={item.id} index={index}>
                    {(provided) => (
                      <div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        style={{
                          ...provided.draggableProps.style,
                          userSelect: 'none',
                          padding: '16px',
                          margin: '0 0 8px 0',
                          backgroundColor: '#fff',
                          border: '1px solid #ccc',
                          borderRadius: '4px',
                        }}
                      >
                        {item.content}
                      </div>
                    )}
                  </Draggable>
                ))}
                {provided.placeholder}
              </div>
            )}
          </Droppable>
        </div>
      </DragDropContext>
    </div>
  );
}
export default Dnd2Compnent;

有了這樣基礎,就可以在增加一些按鈕
例如A移動到B 或者 A全移動到B

又或者增加key事件增加多選項目的功能
也可以在塞個 inputtext 增加搜尋功能

就可以自製一個完美可拖曳的picklist

雖然有預告memo似乎要被移除?
但還好19 還在...(鬆一口氣

終於撐玩30天 真是太好了....
掰~掰


上一篇
Day29 React-beautiful-dnd (1)
系列文
關於寫react 那二三事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言